home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / winsock / twnsck12.zip / SRC\COMMANDS.C < prev    next >
Text File  |  1994-12-03  |  15KB  |  683 lines

  1. /*
  2.  *  TwinSock - "Troy's Windows Sockets"
  3.  *
  4.  *  Copyright (C) 1994  Troy Rollo <troy@cbme.unsw.EDU.AU>
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. #include <stdio.h>
  22. #include <sys/types.h>
  23. #include <netinet/in.h>
  24. #include <netdb.h>
  25. #include <errno.h>
  26. #include <sys/socket.h>
  27. #include "twinsock.h"
  28. #include "tx.h"
  29. #include "wserror.h"
  30.  
  31. #ifdef NEED_H_ERRNO
  32. extern int h_errno;
  33. #endif
  34. #ifdef NO_H_ERRNO
  35. #define h_errno errno
  36. #endif
  37.  
  38. extern void PacketTransmitData (void *pvData, int iDataLen, int iStream);
  39.  
  40. struct
  41. {
  42.     int    iErrnoHost;
  43.     int    iErrnoDos;
  44. } error_mappings[] =
  45. {
  46.     { 0,        0        },
  47.     { EINTR,    WSAEINTR    },
  48.     { EBADF,    WSAEBADF    },
  49.     { EINVAL,    WSAEINVAL    },
  50.     { EMFILE,    WSAEMFILE    },
  51.     { EWOULDBLOCK,    WSAEWOULDBLOCK    },
  52.     { EINPROGRESS,    WSAEINPROGRESS    },
  53.     { EALREADY,    WSAEALREADY    },
  54.     { ENOTSOCK,    WSAENOTSOCK    },
  55.     { EDESTADDRREQ,    WSAEDESTADDRREQ },
  56.     { EMSGSIZE,    WSAEMSGSIZE    },
  57.     { EPROTOTYPE,    WSAEPROTOTYPE    },
  58.     { ENOPROTOOPT,    WSAENOPROTOOPT    },
  59.     { EPROTONOSUPPORT, WSAEPROTONOSUPPORT },
  60.     { ESOCKTNOSUPPORT, WSAESOCKTNOSUPPORT },
  61.     { EOPNOTSUPP,    WSAEOPNOTSUPP    },
  62.     { EPFNOSUPPORT,    WSAEPFNOSUPPORT },
  63.     { EAFNOSUPPORT, WSAEAFNOSUPPORT },
  64.     { EADDRINUSE,    WSAEADDRINUSE    },
  65.     { EADDRNOTAVAIL,WSAEADDRNOTAVAIL },
  66.     { ENETDOWN,    WSAENETDOWN    },
  67.     { ENETUNREACH,    WSAENETUNREACH    },
  68.     { ENETRESET,    WSAENETRESET    },
  69.     { ECONNABORTED,    WSAECONNABORTED    },
  70.     { ECONNRESET,    WSAECONNRESET    },
  71.     { ENOBUFS,    WSAENOBUFS    },
  72.     { EISCONN,    WSAEISCONN    },
  73.     { ENOTCONN,    WSAENOTCONN    },
  74.     { ESHUTDOWN,    WSAESHUTDOWN    },
  75.     { ETOOMANYREFS,    WSAETOOMANYREFS    },
  76.     { ETIMEDOUT,    WSAETIMEDOUT    },
  77.     { ECONNREFUSED,    WSAECONNREFUSED    },
  78.     { ELOOP,    WSAELOOP,    },
  79.     { ENAMETOOLONG,    WSAENAMETOOLONG    },
  80.     { EHOSTDOWN,    WSAEHOSTDOWN    },
  81.     { EHOSTUNREACH,    WSAEHOSTUNREACH    },
  82.     { -1,        -1        }
  83. }, h_error_mappings[] =
  84.     { 0,        0        },
  85.     { HOST_NOT_FOUND, WSAHOST_NOT_FOUND },
  86.     { TRY_AGAIN,    WSATRY_AGAIN    },
  87.     { NO_RECOVERY,    WSANO_RECOVERY    },
  88.     { NO_DATA,    WSANO_DATA    },
  89.     { -1,        -1        }
  90. };
  91.  
  92. /* some functions to allow us to copy integer data
  93.  * to and from unaligned addresses
  94.  */
  95.  
  96. static unsigned short
  97. ToShort(char *pchData)
  98. {
  99.     short    n;
  100.  
  101.     memcpy(&n, pchData, sizeof(short));
  102.     return n;
  103. }
  104.  
  105. static long
  106. ToLong(char *pchData)
  107. {
  108.     long n;
  109.  
  110.     memcpy(&n, pchData, sizeof(long));
  111.     return n;
  112. }
  113.  
  114. static void
  115. FromShort(char *pchData, unsigned short n)
  116. {
  117.     memcpy(pchData, &n, sizeof(short));
  118. }
  119.  
  120. static void
  121. FromLong(char *pchData, long n)
  122. {
  123.     memcpy(pchData, &n, sizeof(long));
  124. }
  125.  
  126. static long
  127. GetIntVal(struct func_arg *pfa)
  128. {
  129.     switch(pfa->at)
  130.     {
  131.     case AT_Int16:
  132.     case AT_Int16Ptr:
  133.         return ntohs(ToShort(pfa->pvData));
  134.  
  135.     case AT_Int32:
  136.     case AT_Int32Ptr:
  137.         return ntohl(ToLong(pfa->pvData));
  138.     }
  139. }
  140.  
  141. void
  142. SetIntVal(struct func_arg *pfa, long iVal)
  143. {
  144.     switch(pfa->at)
  145.     {
  146.     case AT_Int16:
  147.     case AT_Int16Ptr:
  148.         FromShort(pfa->pvData,htons((short) iVal));
  149.         return;
  150.  
  151.     case AT_Int32:
  152.     case AT_Int32Ptr:
  153.         FromLong(pfa->pvData, htonl((short) iVal));
  154.         return;
  155.     }
  156. };
  157.  
  158. struct sockaddr *
  159. ConvertSA(struct func_arg *pfa, struct sockaddr_in *sin)
  160. {
  161.     memcpy(sin, pfa->pvData, sizeof(*sin));
  162.     sin->sin_family = ntohs(sin->sin_family);
  163.     return (struct sockaddr *) sin;
  164. }
  165.  
  166. int
  167. MapError(int iError)
  168. {
  169.     int    i;
  170.  
  171.     for (i = 0; error_mappings[i].iErrnoHost != -1; i++)
  172.     {
  173.         if (error_mappings[i].iErrnoHost == iError)
  174.             return error_mappings[i].iErrnoDos;
  175.     }
  176.     return WSAEFAULT;
  177. }
  178.  
  179. int
  180. MapHError(int iError)
  181. {
  182.     int    i;
  183.  
  184.     for (i = 0; h_error_mappings[i].iErrnoHost != -1; i++)
  185.     {
  186.         if (h_error_mappings[i].iErrnoHost == iError)
  187.             return h_error_mappings[i].iErrnoDos;
  188.     }
  189.     return WSAEFAULT;
  190. }
  191.  
  192. int
  193. CopyString(void *pvData, char *pchString, int iMax)
  194. {
  195.     char    *pchData;
  196.     int    iLen;
  197.  
  198.     pchData = (char *) pvData;
  199.     iLen = strlen(pchString);
  200.     if (iLen + 1 > iMax - 1)
  201.         return 0;
  202.     strcpy(pchData,    pchString);
  203.     return iLen + 1;
  204. }
  205.  
  206. void
  207. CopyHostEnt(void *pvData, struct hostent *phe)
  208. {
  209.     int    iLocation;
  210.     char    *pchData;
  211.     int    i;
  212.  
  213.     pchData = (char *) pvData;
  214.     FromShort(pchData, htons(phe->h_addrtype));
  215.     FromShort(pchData + sizeof(short), htons(phe->h_length));
  216.     for (i = 0; phe->h_addr_list[i]; i++);
  217.     FromShort(pchData + sizeof(short) * 2, htons(i));
  218.     iLocation = sizeof(short) * 3;
  219.     for (i = 0; phe->h_addr_list[i]; i++)
  220.     {
  221.         memcpy(pchData + iLocation, phe->h_addr_list[i], 4);
  222.         iLocation += 4;
  223.     }
  224.     iLocation += CopyString(pchData + iLocation,
  225.                 phe->h_name,
  226.                 MAX_HOST_ENT - iLocation);
  227.     for (i = 0; phe->h_aliases[i]; i++)
  228.     {
  229.         iLocation += CopyString(pchData + iLocation,
  230.                     phe->h_aliases[i],
  231.                     MAX_HOST_ENT - iLocation);
  232.     }
  233.     pchData[iLocation] = 0;
  234. }
  235.  
  236. void
  237. CopyNetEnt(void *pvData, struct netent *pne)
  238. {
  239.     int    iLocation;
  240.     char    *pchData;
  241.     int    i;
  242.  
  243.     pchData = (char *) pvData;
  244.     FromShort(pchData, htons(pne->n_addrtype));
  245.     FromLong(pchData + sizeof(short), pne->n_net);
  246.     iLocation = sizeof(short) + sizeof(long);
  247.     iLocation += CopyString(pchData + iLocation,
  248.                 pne->n_name,
  249.                 MAX_HOST_ENT - iLocation);
  250.     for (i = 0; pne->n_aliases[i]; i++)
  251.     {
  252.         iLocation += CopyString(pchData + iLocation,
  253.                     pne->n_aliases[i],
  254.                     MAX_HOST_ENT - iLocation);
  255.     }
  256.     pchData[iLocation] = 0;
  257. }
  258.  
  259. void
  260. CopyServEnt(void *pvData, struct servent *pse)
  261. {
  262.     int    iLocation;
  263.     char    *pchData;
  264.     int    i;
  265.  
  266.     pchData = (char *) pvData;
  267.     FromShort(pchData, pse->s_port); /* No htons - already in network order */
  268.     iLocation = sizeof(short);
  269.     iLocation += CopyString(pchData + iLocation,
  270.                 pse->s_proto,
  271.                 MAX_HOST_ENT - iLocation);
  272.     iLocation += CopyString(pchData + iLocation,
  273.                 pse->s_name,
  274.                 MAX_HOST_ENT - iLocation);
  275.     for (i = 0; pse->s_aliases[i]; i++)
  276.     {
  277.         iLocation += CopyString(pchData + iLocation,
  278.                     pse->s_aliases[i],
  279.                     MAX_HOST_ENT - iLocation);
  280.     }
  281.     pchData[iLocation] = 0;
  282. }
  283.  
  284. void
  285. CopyProtoEnt(void *pvData, struct protoent *ppe)
  286. {
  287.     int    iLocation;
  288.     char    *pchData;
  289.     int    i;
  290.  
  291.     pchData = (char *) pvData;
  292.     FromShort(pchData, htons(ppe->p_proto));
  293.     iLocation = sizeof(short);
  294.     iLocation += CopyString(pchData + iLocation,
  295.                 ppe->p_name,
  296.                 MAX_HOST_ENT - iLocation);
  297.     for (i = 0; ppe->p_aliases[i]; i++)
  298.     {
  299.         iLocation += CopyString(pchData + iLocation,
  300.                     ppe->p_aliases[i],
  301.                     MAX_HOST_ENT - iLocation);
  302.     }
  303.     pchData[iLocation] = 0;
  304. }
  305.  
  306. void
  307. SwapSockOptIn(    struct func_arg *pfa,
  308.         int    iOpt)
  309. {
  310.     int    iValue;
  311.     char    *pchData;
  312.  
  313.     pchData = (char *) pfa->pvData;
  314.     if (iOpt == SO_LINGER)
  315.     {
  316.         FromShort(pchData, ntohs(ToShort(pchData)));
  317.         FromShort(pchData + sizeof(short),
  318.                 ntohs(ToShort(pchData + sizeof(short))));
  319.     }
  320.     else
  321.     {
  322.         FromLong(pchData, ntohl(ToLong(pchData)));
  323.     }
  324. }
  325.  
  326. void
  327. SwapSockOptOut(    struct func_arg *pfa,
  328.         int    iOpt)
  329. {
  330.     int    iValue;
  331.     char    *pchData;
  332.  
  333.     pchData = (char *) pfa->pvData;
  334.     if (iOpt == SO_LINGER)
  335.     {
  336.         FromShort(pchData, htons(ToShort(pchData)));
  337.         FromShort(pchData + sizeof(short),
  338.                 htons(ToShort(pchData + sizeof(short))));
  339.     }
  340.     else
  341.     {
  342.         FromLong(pchData, htonl(ToLong(pchData)));
  343.     }
  344. }
  345.  
  346. void
  347. ResponseReceived(struct tx_request *ptxr_)
  348. {
  349.     enum Functions ft;
  350.     short    nArgs;
  351.     short    nLen;
  352.     short    id;
  353.     int    iLen;
  354.     int    iValue;
  355.     int    iSocket;
  356.     int    nOptVal;
  357.     short    nError;
  358.     struct    tx_request *ptxr;
  359.     struct    func_arg *pfaArgs;
  360.     struct    func_arg faResult;
  361.     struct    sockaddr_in sin;
  362.     char    *pchData;
  363.     int    i;
  364.     int    iErrorSent;
  365.     int    iOffset;
  366.     struct    hostent *phe;
  367.     struct    netent *pne;
  368.     struct    servent *pse;
  369.     struct    protoent *ppe;
  370.  
  371.     nLen = ntohs(ptxr_->nLen);
  372.     ptxr = (struct tx_request *) malloc(nLen);
  373.     memcpy(ptxr, ptxr_, nLen);
  374.     ft = (enum Functions) ntohs(ptxr->iType);
  375.     nArgs = ntohs(ptxr->nArgs);
  376.  
  377.     pfaArgs = (struct func_arg *) malloc(sizeof(struct func_arg) * nArgs);
  378.     pchData = ptxr->pchData;
  379.     for (i = 0; i < nArgs; i++)
  380.     {
  381.         pfaArgs[i].at = (enum arg_type) ntohs(ToShort(pchData));
  382.         pchData += sizeof(short);
  383.         pfaArgs[i].iLen = ntohs(ToShort(pchData));
  384.         pchData += sizeof(short);
  385.         pfaArgs[i].pvData = pchData;
  386.         pchData += pfaArgs[i].iLen;
  387.     }
  388.     faResult.at = (enum arg_type) ntohs(ToShort(pchData));
  389.     pchData += sizeof(short);
  390.     faResult.iLen = ntohs(ToShort(pchData));
  391.     pchData += sizeof(short);
  392.     faResult.pvData = pchData;
  393.  
  394.     iErrorSent = 0;
  395.     errno = 0;
  396.     h_errno = 0;
  397.  
  398.     switch(ft)
  399.     {
  400.     case FN_IOCtl:
  401.     case FN_Accept:
  402.     case FN_Select:
  403.     case FN_Data:
  404.         ptxr->nError = htons(WSAEOPNOTSUPP);
  405.         ptxr->nLen = htons(sizeof(short) * 5);
  406.         PacketTransmitData(ptxr, sizeof(short) * 5, -2);
  407.         iErrorSent = 1;
  408.         break;
  409.  
  410.     case FN_Send:
  411.         SetIntVal(&faResult,
  412.             send(GetIntVal(&pfaArgs[0]),
  413.                  pfaArgs[1].pvData,
  414.                  GetIntVal(&pfaArgs[2]),
  415.                  GetIntVal(&pfaArgs[3])));
  416.         break;
  417.  
  418.     case FN_SendTo:
  419.         SetIntVal(&faResult,
  420.             sendto(GetIntVal(&pfaArgs[0]),
  421.                    pfaArgs[1].pvData,
  422.                    GetIntVal(&pfaArgs[2]),
  423.                    GetIntVal(&pfaArgs[3]),
  424.                    ConvertSA(&pfaArgs[4], &sin),
  425.                    GetIntVal(&pfaArgs[5])));
  426.         break;
  427.  
  428.     case FN_Bind:
  429.         SetIntVal(&faResult,
  430.             bind(GetIntVal(&pfaArgs[0]),
  431.                  ConvertSA(&pfaArgs[1], &sin),
  432.                  GetIntVal(&pfaArgs[2])));
  433.         break;
  434.  
  435.     case FN_Connect:
  436.         iSocket = GetIntVal(&pfaArgs[0]);
  437.         iValue = connect(iSocket,
  438.                 ConvertSA(&pfaArgs[1], &sin),
  439.                 GetIntVal(&pfaArgs[2]));
  440.         SetIntVal(&faResult, iValue);
  441.         if (iValue != -1)
  442.             BumpLargestFD(iSocket);
  443.         break;
  444.  
  445.     case FN_Close:
  446.         SetIntVal(&faResult,
  447.             close(GetIntVal(&pfaArgs[0])));
  448.         FlushStream(GetIntVal(&pfaArgs[0]));
  449.         SetClosed(GetIntVal(&pfaArgs[0]));
  450.         break;
  451.  
  452.     case FN_Shutdown:
  453.         SetIntVal(&faResult,
  454.             shutdown(GetIntVal(&pfaArgs[0]),
  455.                  GetIntVal(&pfaArgs[1])));
  456.         if (GetIntVal(&pfaArgs[1]) != 1)
  457.             SetClosed(GetIntVal(&pfaArgs[0]));
  458.         break;
  459.  
  460.     case FN_Listen:
  461.         iSocket = GetIntVal(&pfaArgs[0]);
  462.         iValue = listen(iSocket,
  463.                 GetIntVal(&pfaArgs[1]));
  464.         SetIntVal(&faResult, iValue);
  465.         if (iValue != -1)
  466.         {
  467.             BumpLargestFD(iSocket);
  468.             SetListener(iSocket);
  469.         }
  470.         break;
  471.  
  472.     case FN_Socket:
  473.         iSocket = socket(GetIntVal(&pfaArgs[0]),
  474.                 GetIntVal(&pfaArgs[1]),
  475.                 GetIntVal(&pfaArgs[2]));
  476.         SetIntVal(&faResult,iSocket);
  477.         if (iSocket != -1)
  478.         {
  479.             BumpLargestFD(iSocket);
  480.             nOptVal = 1;
  481.             iLen = sizeof(nOptVal);
  482.             setsockopt(iSocket,
  483.                     SOL_SOCKET,
  484.                     SO_OOBINLINE,
  485.                     (char *) &nOptVal,
  486.                     iLen);
  487.             errno = 0;
  488.         }
  489.         break;
  490.  
  491.     case FN_GetPeerName:
  492.         iLen = GetIntVal(&pfaArgs[2]);
  493.         iValue = getpeername(GetIntVal(&pfaArgs[0]),
  494.                      (struct sockaddr *) pfaArgs[1].pvData,
  495.                      &iLen);
  496.         if (iValue != -1)
  497.         {
  498.             SetIntVal(&faResult, iValue);
  499.             SetIntVal(&pfaArgs[2], iValue);
  500.             iValue = ((struct sockaddr *) pfaArgs[1].pvData)->
  501.                         sa_family;
  502.             iValue = htons((short) iValue);
  503.             ((struct sockaddr *) pfaArgs[1].pvData)->sa_family =
  504.                         (short) iValue;
  505.         }
  506.         break;
  507.  
  508.     case FN_GetSockName:
  509.         iLen = GetIntVal(&pfaArgs[2]);
  510.         iValue = getsockname(GetIntVal(&pfaArgs[0]),
  511.                      (struct sockaddr *) pfaArgs[1].pvData,
  512.                      &iLen);
  513.         if (iValue != -1)
  514.         {
  515.             SetIntVal(&faResult, iValue);
  516.             SetIntVal(&pfaArgs[2], iValue);
  517.             iValue = ((struct sockaddr *) pfaArgs[1].pvData)->
  518.                         sa_family;
  519.             iValue = htons((short) iValue);
  520.             ((struct sockaddr *) pfaArgs[1].pvData)->sa_family =
  521.                         (short) iValue;
  522.         }
  523.         break;
  524.  
  525.     case FN_GetSockOpt:
  526.         iLen = GetIntVal(&pfaArgs[4]);
  527.         iValue = getsockopt(    GetIntVal(&pfaArgs[0]),
  528.                     GetIntVal(&pfaArgs[1]),
  529.                     GetIntVal(&pfaArgs[2]),
  530.                     (char *) pfaArgs[3].pvData,
  531.                     &iLen);
  532.         if (iValue != -1)
  533.         {
  534.             SwapSockOptOut(&pfaArgs[3],
  535.                     GetIntVal(&pfaArgs[2]));
  536.             SetIntVal(&pfaArgs[4], iLen);
  537.         }
  538.         SetIntVal(&faResult, iValue);
  539.         break;
  540.  
  541.     case FN_SetSockOpt:
  542.         iLen = GetIntVal(&pfaArgs[4]);
  543.         SwapSockOptIn(&pfaArgs[3],
  544.                 GetIntVal(&pfaArgs[2]));
  545.         iValue = setsockopt(    GetIntVal(&pfaArgs[0]),
  546.                     SOL_SOCKET,
  547.                     GetIntVal(&pfaArgs[2]),
  548.                     (char *) pfaArgs[3].pvData,
  549.                     iLen);
  550.         SwapSockOptOut(&pfaArgs[3],
  551.                 GetIntVal(&pfaArgs[2]));
  552.         SetIntVal(&faResult, iValue);
  553.         break;
  554.  
  555.     case FN_GetHostName:
  556.         SetIntVal(&faResult,
  557.             gethostname((char *) pfaArgs[0].pvData,
  558.                     GetIntVal(&pfaArgs[1])));
  559.         break;
  560.  
  561.     case FN_HostByAddr:
  562.         phe = gethostbyaddr((char *) pfaArgs[0].pvData,
  563.                     GetIntVal(&pfaArgs[1]),
  564.                     GetIntVal(&pfaArgs[2]));
  565.         if (phe)
  566.         {
  567.             h_errno = 0;
  568.             CopyHostEnt(faResult.pvData, phe);
  569.         }
  570.         break;
  571.  
  572.     case FN_HostByName:
  573.         phe = gethostbyname((char *) pfaArgs[0].pvData);
  574.         if (phe)
  575.         {
  576.             h_errno = 0;
  577.             CopyHostEnt(faResult.pvData, phe);
  578.         }
  579.         else if (!h_errno)
  580.         {
  581.             h_errno = TRY_AGAIN;
  582.         }
  583.         break;
  584.  
  585.     case FN_ServByPort:
  586.         if (pfaArgs[0].at == AT_Int16)
  587.             iValue = *(short *) pfaArgs[0].pvData;
  588.         else
  589.             iValue = *(long *) pfaArgs[0].pvData;
  590.         pse = getservbyport(iValue,
  591.                     (char *) pfaArgs[1].pvData);
  592.         if (pse)
  593.         {
  594.             h_errno = 0;
  595.             CopyServEnt(faResult.pvData, pse);
  596.         }
  597.         else
  598.         {
  599.             h_errno = NO_DATA;
  600.         }
  601.         break;
  602.  
  603.     case FN_ServByName:
  604.         pse = getservbyname((char *) pfaArgs[0].pvData,
  605.                     (char *) pfaArgs[1].pvData);
  606.         if (pse)
  607.         {
  608.             h_errno = 0;
  609.             CopyServEnt(faResult.pvData, pse);
  610.         }
  611.         else
  612.         {
  613.             h_errno = NO_DATA;
  614.         }
  615.         break;
  616.  
  617.     case FN_ProtoByNumber:
  618.         ppe = getprotobynumber(GetIntVal(&pfaArgs[0]));
  619.         if (ppe)
  620.         {
  621.             h_errno = 0;
  622.             CopyProtoEnt(faResult.pvData, ppe);
  623.         }
  624.         else
  625.         {
  626.             h_errno = NO_DATA;
  627.         }
  628.         break;
  629.  
  630.     case FN_ProtoByName:
  631.         ppe = getprotobyname((char *) pfaArgs[0].pvData);
  632.         if (ppe)
  633.         {
  634.             h_errno = 0;
  635.             CopyProtoEnt(faResult.pvData, ppe);
  636.         }
  637.         else
  638.         {
  639.             h_errno = NO_DATA;
  640.         }
  641.         break;
  642.     }
  643.     if (!iErrorSent)
  644.     {
  645.         if (ft >= FN_HostByAddr && ft <= FN_ProtoByName)
  646.             ptxr->nError = htons(MapHError(h_errno));
  647.         else
  648.             ptxr->nError = htons(MapError(errno));
  649.         PacketTransmitData(ptxr, nLen, -2);
  650.     }
  651.     free(ptxr);
  652.     free(pfaArgs);
  653. }
  654.  
  655. void
  656. SendSocketData(int iSocket,
  657.         void    *pvData,
  658.         int    iLen,
  659.         struct sockaddr_in *psa,
  660.         int    iAddrLen,
  661.         enum Functions ft)
  662. {
  663.     struct    tx_request *ptxr;
  664.     int    iDataLen;
  665.     struct    sockaddr_in sa;
  666.  
  667.     iDataLen = sizeof(struct sockaddr_in) + iLen;
  668.     sa = *psa;
  669.     sa.sin_family = htons(sa.sin_family);
  670.     ptxr = (struct tx_request *) malloc(sizeof(short) * 5 + iDataLen);
  671.     ptxr->nLen = htons(iDataLen + sizeof(short) * 5);
  672.     ptxr->id = htons(iSocket);
  673.     ptxr->nArgs = 0;
  674.     ptxr->nError = 0;
  675.     ptxr->iType = htons(ft);
  676.     memcpy(ptxr->pchData, &sa, sizeof(sa));
  677.     memcpy(ptxr->pchData + sizeof(sa), pvData, iLen);
  678.     PacketTransmitData(ptxr, sizeof(short) * 5 + iDataLen,
  679.         (ft == FN_Data) ? iSocket : -2);
  680.     free(ptxr);
  681. }
  682.